//
//  VideoDetailController.swift
//  视频详情
//
//  Created by smile on 2019/7/5.
//  Copyright © 2019 ixuea. All rights reserved.
//

import UIKit

// 键盘管理器
// 目的是键盘弹出时
// 相应的控件自动上移避免挡住
import KeyboardLayoutGuide

//导入媒体播放框架
import MediaPlayer

class VideoDetailController: BaseTitleController {
    
    // MARK: - 控件
    
    @IBOutlet weak var videoContainerHeight: NSLayoutConstraint!
    
    /// 视频容器
    @IBOutlet weak var videoContainer: UIView!
    
    /// 播放按钮
    @IBOutlet weak var btPlay: UIButton!
    
    /// 重新播放按钮
    @IBOutlet weak var btReply: UIButton!
    
    /// 信息
    @IBOutlet weak var lbInfo: UILabel!
    
    /// 开始时间
    @IBOutlet weak var lbStart: UILabel!
    
    /// 进度条
    @IBOutlet weak var sdProgress: UISlider!
    
    /// 结束时间
    @IBOutlet weak var lbEnd: UILabel!
    
    /// 横竖屏切换按钮
    @IBOutlet weak var brOrientation: UIButton!
    
    /// 播放相关控制容器
    @IBOutlet weak var controlContainer: UIStackView!
    
    /// 列表控件
    @IBOutlet weak var tableView: UITableView!
    
    /// 输入框容器
    @IBOutlet weak var vwInputContainer: UIView!
    
    /// 输入框边框容器
    @IBOutlet weak var vwInputBorder: UIView!
    
    /// 评论数图片
    @IBOutlet weak var ivCommentCount: UIImageView!
    
    /// 评论数文本
    @IBOutlet weak var lbCommentCount: UILabel!
    
    // MARK: - 数据
    /// Id
    var id:String!
    
    /// 视频
    var data:Video!
    
    /// 列表数据源
    var dataArray:[VideoDetailGroup] = []
    
    /// 评论标题的位置
    var commentPosition = 0
    
    /// 视频播放管理器
    var videoPlayerManager:VideoPlayerManager!
    
    /// 显示视频画面的控件
    var playLayer:AVPlayerLayer!
    
    /// 隐藏控制器
    var task:DispatchWorkItem?
    
    /// 是否恢复播放
    var isResumePlay = false
    
    /// 视频容器竖屏高度
    //这个值不是随便写的
    //而是在iPhone尺寸上
    //根据1920*1080视频缩放的近似值
    var videoContainerHeightPortrait:CGFloat = 210
    
    // MARK: - 右侧按钮点击回调方法
    
    /// 右侧分享按钮点击
    ///
    /// - Parameter sender: <#sender description#>
    @objc func onShareClick(sender:UIButton) {
        print("VideoDetailController onShareClick")
    }
    
    /// 右侧更多按钮点击
    @objc func onMoreClick() {
       print("VideoDetailController onMoreClick")
    }
    
    // MARK: - 生命周期
    override func initViews() {
        super.initViews()
        
        //创建右侧按钮
        //分享
        let shareBarItem = UIBarButtonItem(image: UIImage(named: "Share"), style: .plain, target: self, action: #selector(onShareClick(sender:)))
        
        //更多按钮
        let moreBarItem = UIBarButtonItem(image: UIImage(named: "MoreWhite"), style: .plain, target: self, action: #selector(onMoreClick))
        
        //将按钮添加到导航栏
        navigationItem.rightBarButtonItems=[moreBarItem,shareBarItem]
        
        //进度条
        sdProgress.minimumTrackTintColor=UIColor(hex: COLOR_PRIMARY)
        sdProgress.thumbTintColor=UIColor(hex: COLOR_PRIMARY)
        
        let thumbImage=UIImage(named: "ProgressThumb")
        sdProgress.setThumbImage(thumbImage, for: .normal)
        sdProgress.setThumbImage(thumbImage, for: .highlighted)
        
        //重新播放按钮圆角
        ViewUtil.showRadius(btReply, 15)
        
        //重新播放按钮边框
        btReply.showColorPrimaryBorder()
        
        //输入框圆角
        ViewUtil.showSmallRadius(vwInputBorder)
        
        //输入框边框
        vwInputBorder.showColorPrimaryBorder()
        
        //避免输入框被输入法挡住
        vwInputContainer.bottomAnchor.constraint(equalTo: view.keyboardLayoutGuide.topAnchor).isActive=true
        
        // 禁用返回手势
        //navigationController?.interactivePopGestureRecognizer?.isEnabled=false
        
        //注册视频详情Cell
        tableView.register(UINib(nibName: VideoDetailInfoCell.NAME, bundle: nil), forCellReuseIdentifier: VideoDetailInfoCell.NAME)
        
        //注册用户section
        tableView.register(UINib(nibName: VideoDetailUserInfoHeaderView.NAME, bundle: nil), forHeaderFooterViewReuseIdentifier: VideoDetailUserInfoHeaderView.NAME)
        
        //注册标题
        tableView.register(UINib(nibName: TitleTableViewCell.NAME, bundle: nil), forCellReuseIdentifier: TitleTableViewCell.NAME)
        
        //注册相关视频
        tableView.register(UINib(nibName: VideoDetailVideoCell.NAME, bundle: nil), forCellReuseIdentifier: VideoDetailVideoCell.NAME)
        
        //注册评论
        tableView.register(UINib(nibName: CommentCell.NAME, bundle: nil), forCellReuseIdentifier: CommentCell.NAME)
        
        //支持自动转屏
        AppDelegate.shared.orientationMask = .all
    }
    
    override func initDatas() {
        super.initDatas()
        
        Api.shared.videoDetail(id).subscribeOnSuccess { (data) in
            if let data = data?.data {
                self.showData(data)
            }
        }.disposed(by: disposeBag)
        
        //初始化播放视频管理器
        videoPlayerManager=VideoPlayerManager.shared
        
        //显示视频画面的layer
        playLayer = videoPlayerManager.playerLayer
        
        //把layer添加到界面
        videoContainer.layer.insertSublayer(playLayer, at: 0)
        
        //设置播放代理
        videoPlayerManager.delegate=self
    }
    
    override func initListeners() {
        super.initListeners()
        //开启监听设备屏幕方向
        //如果不开启就监听不到
        if !UIDevice.current.isGeneratingDeviceOrientationNotifications {
            UIDevice.current.beginGeneratingDeviceOrientationNotifications()
        }
        
        //注册屏幕方向改变通知
        NotificationCenter.default.addObserver(self, selector: #selector(onDeviceOrientationChanged(notification:)), name: UIDevice.orientationDidChangeNotification, object: nil)
        
        //监听进入后台
        NotificationCenter.default.addObserver(self, selector: #selector(onEnterForeground), name: UIApplication.didBecomeActiveNotification, object: nil)
        
        //监听进入后台
        NotificationCenter.default.addObserver(self, selector: #selector(onEnterBackground), name: UIApplication.willResignActiveNotification, object: nil)
    }
    
    // MARK: - 屏幕方向
    
    /// 屏幕方向改变了调用
    ///
    /// - Parameter notification: <#notification description#>
    @objc func onDeviceOrientationChanged(notification:Notification) {
        //获取当前屏幕方向
        let deviceOrientation = UIDevice.current.orientation
        
        switch deviceOrientation {
        case .landscapeLeft:
            print("屏幕向左横置")
            onDeviceOrientationLandscape()
        case .landscapeRight:
            print("屏幕向右横置")
            onDeviceOrientationLandscape()
        case .portrait:
            print("屏幕直立")
            onDeviceOrientationPortrait()
        default:
            break
        }
    }
    
    /// 横屏
    func onDeviceOrientationLandscape() {
        //视频容器的高度就是View高度
        videoContainerHeight.constant = view.frame.height
        
        //设置图标为切换为竖屏图标
        brOrientation.setImage(UIImage(named: "NormalScreen"), for: .normal)
    }
    
    /// 竖屏
    func onDeviceOrientationPortrait() {
        //视频容器的高度为视频高度
        videoContainerHeight.constant = videoContainerHeightPortrait
        
        //设置图标为切换到全屏图片
        brOrientation.setImage(UIImage(named: "FullScreen"
        ), for: .normal)
    }
    
    /// 设置屏幕方向
    ///
    /// - Parameter data: <#data description#>
    func setOrientation(_ data:UIDeviceOrientation) {
        UIDevice.current.setValue(data.rawValue, forKey: "orientation")
    }
    
    /// 进入前台了
    @objc func onEnterForeground() {
        checkIfResume()
    }
    
    /// 进入后台了
    @objc func onEnterBackground() {
        checkIfPause()
    }
    
    /// 是否继续播放
    func checkIfResume() {
        if isResumePlay {
            resume()
            
            isResumePlay=false
        }
    }
    
    /// 是否暂停
    func checkIfPause() {
        if videoPlayerManager.isPlaying() {
            isResumePlay = true
            
            //暂停
            pause()
        }
    }
    
    /// 已经布局了
    /// 当切换横竖屏是也会调用
    /// 所以直接在该方法中更改播放视频的layer
    /// 就能完成视频播放横竖屏切换
    override func viewDidLayoutSubviews() {
        //重新设置layer尺寸和位置
        playLayer.frame = videoContainer.bounds
        
        print("VideoDetailController viewDidLayoutSubViews:\(videoContainer.bounds)")
    }
    
    /// 显示数据
    ///
    /// - Parameter data: <#data description#>
    func showData(_ data:Video) {
        self.data=data
        
        print("VideoDetetailController showData:\(data.title)")
        
        play(data.uri)
        
        //准备其他数据
        //包括：相关视频；评论
        prepareData()
        
        //启动隐藏控制器定时器
        startHideController()
    }
    
    /// 播放视频
    ///
    /// - Parameter uri: <#uri description#>
    func play(_ data:String) {
        //播放在线视频
        videoPlayerManager.play(ResourceUtil.resourceUri(data), self.data)
        
        //本地视频
        //文件放到项目根目录中
//        let localVideoPath=Bundle.main.path(forResource: "ixueaedu", ofType: ".mp4")!
//
//        videoPlayerManager.play(localVideoPath, self.data)
    }
    
    /// 准备数据
    func prepareData() {
        //组装数据
        //第一组
        let fristGroup=VideoDetailGroup()
        
        //组标题
        fristGroup.data=nil
        
        //这一组列表数据
        fristGroup.datas=[data]
        
        //添加到数据源中
        dataArray.append(fristGroup)
        
        //第二组
        let secondGroup=VideoDetailGroup()
        
        //组标题
        secondGroup.data=data.user
        
        //这一组数据
        secondGroup.datas=[]
        
        //添加组到数据源中
        dataArray.append(secondGroup)
        
        //添加相关视频标题
        secondGroup.datas.append("相关推荐")
        
        //请求相关视频数据
        Api.shared.videos().subscribeOnSuccess { (data) in
            if let data=data?.data?.data {
                print("VideoDetailController prepareData video list succes:\(data.count)")
                
                //把数据添加到第二组
                secondGroup.datas=secondGroup.datas+data
                
                //添加评论标题
                secondGroup.datas.append("热门评论")
                
                //计算评论位置
                self.commentPosition=1+data.count
                
                //请求热门评论数据
                //请求评论
                Api.shared.comments().subscribeOnSuccess { (listResponse) in
                    if let data=listResponse?.data?.data{
                        //将数据添加到第二组
                        secondGroup.datas=secondGroup.datas+data
                        
                        print("VideoDetailController prepareData comment list success:\(data.count)")
                        
                        //重新加载数据
                        self.tableView.reloadData()
                        
                        //显示评论数量
                        self.lbCommentCount.text="\(listResponse!.data!.total_count)"
                    }
                }.disposed(by: self.disposeBag)
                
            }
        }.disposed(by: disposeBag)
        
        
    }
    
    /// 界面即将显示调用
    ///
    /// - Parameter animated: <#animated description#>
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        //设置标题栏为亮色
        setTitleBarLight()
    }
    
    /// 界面即将消失
    ///
    /// - Parameter animated: <#animated description#>
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        
        //设置标题栏为默认颜色
        setTitleBarDefault()
        
        //停止播放
        checkIfPause()
        
        //恢复为竖屏
        AppDelegate.shared.orientationMask = .portrait
    }
    
    // MARK: - 按钮相关
    
 
    /// 播放控制层点击
    ///
    /// - Parameter sender: <#sender description#>
    @IBAction func onPlayControlClick(_ sender: Any) {
        print("VideoDetailController onPlayControlClick")
        
        showOrHideController()
    }
    
    /// 播放按钮点击
    ///
    /// - Parameter sender: <#sender description#>
    @IBAction func onPlayClick(_ sender: Any) {
        print("VideoDetailController onPlayClick")
        
        playOrPause()
    }
    
    /// 重新播放按钮点击
    ///
    /// - Parameter sender: <#sender description#>
    @IBAction func onReplyClick(_ sender: Any) {
        print("VideoDetailController onReplyClick")
        
        play(data.uri)
    }
    
    /// 横竖屏切换按钮点击
    ///
    /// - Parameter sender: <#sender description#>
    @IBAction func onOrientationClick(_ sender: Any) {
        print("VideoDetailController onOrientationClick")
        
        //获取当前屏幕方向
        let deviceOrientation = UIDevice.current.orientation
        
        if deviceOrientation == .portrait {
            //竖屏
            
            //切换为横屏
            setOrientation(.landscapeLeft)
        } else {
            //其他方向
            
            //切换为竖屏
            setOrientation(.portrait)
        }
    }
    
    /// 列表控制按钮点击
    ///
    /// - Parameter sender: <#sender description#>
    @IBAction func onListClick(_ sender: Any) {
        print("VideoDetailController onListClick")
        
        var indexPath:IndexPath!
        
        if lbCommentCount.isHidden {
            //滚动到顶部
            indexPath=IndexPath(item: 0, section: 0)
        } else {
            //滚动到评论
            indexPath=IndexPath(item: commentPosition, section: 1)
        }
        
        //滚动
        tableView.scrollToRow(at: indexPath, at: .top, animated: true)
    }
    
    // MARK: - 进度条
    
    /// 进度条改变
    ///
    /// - Parameter sender: <#sender description#>
    @IBAction func onProgressChanged(_ sender: UISlider) {
        print("VideoDetailController onProgressChanged:\(sender.value)")
        
        videoPlayerManager.seekTo(sender.value)
    }
    
    /// 获取cell类型
    ///
    /// - Parameter indexPath: <#indexPath description#>
    /// - Returns: <#return value description#>
    func typeForItemAtIndex(_ indexPath:IndexPath) -> CellType {
        let group=dataArray[indexPath.section]
        let data=group.datas[indexPath.row]
        
        if indexPath.section==0 && indexPath.row==0 {
            //第一组第一个
            return .videoInfo
        } else if data is String {
            //标题
            return .title
        }else if data is Video{
            //相关视频
            return .video
        }
        
        //TODO 更多类型在这里添加就行了
        
        //评论
        return .comment
    }
    
    /// 显示滚动到顶部UI
    func showScrollTopUI() {
        lbCommentCount.isHidden=true
        ivCommentCount.image=UIImage(named: "BackTop")
    }
    
    /// 显示滚动到评论UI
    func showScrollCommentUI() {
        lbCommentCount.isHidden=false
        ivCommentCount.image=UIImage(named: "CommentCountText")
    }
    
    /// Cell类型
    ///
    /// - videoInfo: 视频信息
    /// - title: 标题；相关推荐
    /// - video: 相关视频
    /// - comment: 评论
    enum CellType {
        case videoInfo
        case title
        case video
        case comment
    }
    
    // MARK: - 播放相关
    
    /// 显示播放进度
    func showProgress() {
        sdProgress.setValue(data.progress, animated: true)
        
        lbStart.text=TimeUtil.second2MinuteAndSecond(data.progress)
    }
    
    /// 隐藏控制器
    func hideController() {
        controlContainer.isHidden=true
        
        btPlay.isHidden=true
        
        //隐藏导航栏
        navigationController?.setNavigationBarHidden(true, animated: false)
        
        cancelTask()
    }
    
    /// 取消倒计时任务
    func cancelTask() {
        if let task = task {
            task.cancel()
            self.task=nil
        }
    }
    
    /// 显示播放状态
    func showPlayStatus() {
        btPlay.setImage(UIImage(named: "VideoPlay"), for: .normal)
    }
    
    /// 显示暂停状态
    func showPauseStatus() {
        btPlay.setImage(UIImage(named: "VideoPause"), for: .normal)
        
        btReply.isHidden=true
        lbInfo.isHidden=true
    }
    
    /// 播放失败
    func onPlayFailed(){
        btReply.isHidden=false
        btPlay.isHidden=true
        
        btReply.setTitle(" 点击重试 ", for: .normal)
        lbInfo.text="播放失败！"
    }
    
    /// 播放或者暂停
    func playOrPause() {
        if videoPlayerManager.isPlaying() {
            pause()
        } else {
            resume()
        }
    }
    
    /// 暂停
    func pause() {
        videoPlayerManager.pause()
    }
    
    /// 继续播放
    func resume() {
        videoPlayerManager.resume()
    }
    
    /// 显示和隐藏控制器
    func showOrHideController() {
        if controlContainer.isHidden {
            //隐藏了
            
            //显示
            if Int(data.progress) != data.duration{
                //播放完毕了
                //就不显示
                controlContainer.isHidden=false
                btPlay.isHidden=false
            }
            
            //显示导航栏
            navigationController?.setNavigationBarHidden(false, animated: false)
            
            startHideController()
        } else {
            //已经显示了
            
            //隐藏
            hideController()
        }
    }
    
    /// 开始隐藏控制器倒计时
    func startHideController() {
        //创建一个任务
        task=DispatchWorkItem(block: {
            self.hideController()
        })
        
        //5秒钟后执行
        DispatchQueue.main.asyncAfter(deadline: .now()+5, execute: task!)
    }
    
}

// MARK: - 启动方法
extension VideoDetailController{
    
    /// 启动方法
    ///
    /// - Parameters:
    ///   - nav: <#nav description#>
    ///   - id: <#id description#>
    static func start(_ nav:UINavigationController,_ id:String) {
        //创建控制器
        let controller=nav.storyboard!.instantiateViewController(withIdentifier: "VideoDetail") as! VideoDetailController
        
        //传递参数
        controller.id=id
        
        //将控制器放到导航控制器
        nav.pushViewController(controller, animated: true)
    }
}

// MARK: - 列表数据源和代理
extension VideoDetailController:UITableViewDataSource,UITableViewDelegate{
    
    /// 有多少组
    ///
    /// - Parameter tableView: <#tableView description#>
    /// - Returns: <#return value description#>
    func numberOfSections(in tableView: UITableView) -> Int {
        return dataArray.count
    }
    
    /// 有多少个
    ///
    /// - Parameters:
    ///   - tableView: <#tableView description#>
    ///   - section: <#section description#>
    /// - Returns: <#return value description#>
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        let data = dataArray[section]
        return data.datas.count
    }
    
    /// 返回自地沟油的Header（Section）
    ///
    /// - Parameters:
    ///   - tableView: <#tableView description#>
    ///   - section: <#section description#>
    /// - Returns: <#return value description#>
    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        //取出组数据
        let group=dataArray[section]
        
        //获取header
        let header=tableView.dequeueReusableHeaderFooterView(withIdentifier: VideoDetailUserInfoHeaderView.NAME) as! VideoDetailUserInfoHeaderView
        
        //绑定数据
        if let data = group.data {
            header.bindData(data)
        }
        
        //返回header
        return header
    }
    
    /// 返回Cell
    ///
    /// - Parameters:
    ///   - tableView: <#tableView description#>
    ///   - indexPath: <#indexPath description#>
    /// - Returns: <#return value description#>
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let group=dataArray[indexPath.section]
        let data=group.datas[indexPath.row]
        
        //获取cell类型
        let type=typeForItemAtIndex(indexPath)
        
        switch type {
        case .videoInfo:
            //视频信息
            let cell = tableView.dequeueReusableCell(withIdentifier: VideoDetailInfoCell.NAME, for: indexPath) as! VideoDetailInfoCell
            
            //绑定数据
            cell.bindData( data as! Video)
            
            //返回cell
            return cell
        case .title:
            //标题
            let cell = tableView.dequeueReusableCell(withIdentifier: TitleTableViewCell.NAME, for: indexPath) as! TitleTableViewCell
            
            //绑定数据
            cell.bindData(data as! String)
            
            //返回cell
            return cell
        case .video:
            //相关视频
            let cell=tableView.dequeueReusableCell(withIdentifier: VideoDetailVideoCell.NAME, for: indexPath) as! VideoDetailVideoCell
            
            //绑定数据
            cell.bindData(data as! Video)
            
            //返回cell
            return cell
        default:
            //评论
            let cell=tableView.dequeueReusableCell(withIdentifier: CommentCell.NAME, for: indexPath) as! CommentCell
            
            //绑定数据
            cell.bindData(data as! Comment)
            
            //返回cell
            return cell
        }
    }
    
    /// 组高度
    ///
    /// - Parameters:
    ///   - tableView: <#tableView description#>
    ///   - section: <#section description#>
    /// - Returns: <#return value description#>
    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        if section==1 {
            //只有 有用户信息才有高度
            return 50
        }
        
        //其他组不显示section
        return 0
    }
    
    /// 滚动中
    ///
    /// - Parameter scrollView: <#scrollView description#>
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        //获取滚动距离
        //如果大于100就显示返回到顶部
        //该值可以根据业务逻辑更改
        let offsetY = scrollView.contentOffset.y
        
        if offsetY>100 {
            showScrollTopUI()
        } else {
            showScrollCommentUI()
        }
    }
}

// MARK: - 播放代理
extension VideoDetailController:VideoPlayerDelegate {
    
    /// 进度回调
    ///
    /// - Parameter data: <#data description#>
    func onProgress(_ data: Video) {
        showProgress()
    }
    
    /// 暂停了
    ///
    /// - Parameter data: <#data description#>
    func onPaused(_ data: Video) {
        showPlayStatus()
    }
    
    /// 正在播放
    ///
    /// - Parameter data: <#data description#>
    func onPlaying(_ data: Video) {
        showPauseStatus()
    }
    
    /// 播放器准备完毕了
    ///
    /// - Parameter data: <#data description#>
    func onPrepared(_ data: Video) {
        sdProgress.maximumValue=Float(data.duration)
        
        lbEnd.text=TimeUtil.second2MinuteAndSecond(Float(data.duration))
        
        //开启滑块功能
        sdProgress.isEnabled=true
    }
    
    /// 播放错误了
    ///
    /// - Parameters:
    ///   - data: <#data description#>
    ///   - error: <#error description#>
    func onError(_ data: Video, _ error: Error?) {
        onPlayFailed()
    }
    
    /// 播放完毕了
    ///
    /// - Parameter data: <#data description#>
    func onComplete(_ data: Video) {
        //真实项目中
        //播放完毕了
        //可能会自动播放下一首
        //和音乐差不多
        //这里就不实现了
        hideController()
        
        btReply.isHidden=false
        btReply.setTitle(" 重新播放 ", for: .normal)
    }
    
    
    
}
